﻿Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Imports Microsoft.Office.Interop
Imports PTIC_Util
Imports PTIC_Util.GestionCalculs
Imports System.Collections.ObjectModel

#Region "TableBDD"
''' <summary>
''' Traitement représentant l'import d'une table de la base de données
''' </summary>
''' <remarks></remarks>
<Serializable()> Public MustInherit Class tableBDD
    Inherits Traitement

#Region "Variables de classe"

    <NonSerialized()> Private _slNomTablesDispoBDD As New ObservableCollection(Of String)
    <NonSerialized()> Private _dttbleMetaDonnees As DataTable
    <NonSerialized()> Private _statistiquesTable As New statsTableBDD
    Private _ListeChampsEntree As New ListeChampsEntreeTable()

    'Etat de la récupération sous forme de dataTable de la table physique retenue par défaut
    Protected m_etatExecDataTableSortie As EtatCalcul

#End Region

#Region "Constructeur"

    ''' <summary>
    ''' Constructeur (caractéristiques physiques non connues)
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New(ByVal nomTraitement As String, _
                   Optional ByVal initialiseur As initialiseurTableBDD = Nothing, _
                   Optional ByVal DataSet As DataSet = Nothing)
        MyBase.New(nomTraitement, DataSet)
        If initialiseur Is Nothing Then
            initialiseur = New initialiseurTableBDDdefaut()
        End If
        ListeChampsSortie = initialiseur.construitListeChampsSortieTable()
        ListeChampsSortie.initialise(Me)
        m_etatExecDataTableSortie = New EtatCalcul(PTIC_Util.ValueEtatCalcul.A_MAJ)
    End Sub

    ''' <summary>
    ''' Constructeur
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub New(ByVal nomTraitement As String, _
               ByVal NomFichier As Cla_NomFichier, _
               ByVal typeSupportSce As typeBase, _
               Optional ByVal initialiseur As initialiseurTableBDD = Nothing, _
               Optional ByVal DataSet As DataSet = Nothing)
        MyBase.New(nomTraitement, DataSet)
        FichierBDD.NomComplet = NomFichier.NomComplet
        If initialiseur Is Nothing Then
            initialiseur = New initialiseurTableBDDdefaut()
        End If
        ListeChampsSortie = initialiseur.construitListeChampsSortieTable()
        ListeChampsSortie.initialise(Me)
        m_etatExecDataTableSortie = New EtatCalcul(PTIC_Util.ValueEtatCalcul.A_MAJ)
    End Sub

#End Region

#Region "propriétés"

    ''' <summary>
    ''' Liste des champs présents dans le fichier physique
    ''' </summary>
    ''' <remarks></remarks>
    Public Property ListeChampsEntree() As ListeChampsEntreeTable
        Get
            Return _ListeChampsEntree
        End Get
        Protected Set(ByVal value As ListeChampsEntreeTable)
            OnPropertyChanging("ListeChampsEntree")
            _ListeChampsEntree = value
            OnPropertyChanged("ListeChampsEntree")
        End Set
    End Property

    ''' <summary>
    ''' Renvoie les statistiques de la table retenue
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property StatsTable() As statsTableBDD
        Get
            Return _statistiquesTable
        End Get
    End Property

    ''' <summary>
    ''' Liste des tables disponibles dans le chemin référencé par la tableBDD
    ''' </summary>
    ''' <returns>Collection de String contenant les noms des tables disponibles dans la tableBDD</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ListTablesDispoBDD() As System.Collections.ObjectModel.ObservableCollection(Of String)
        Get
            Return _slNomTablesDispoBDD
        End Get
    End Property

    ''' <summary>
    ''' Liste des champs présent dans l'extraction de la table (overloads pour le typage de la propriété dans l'intellisense)
    ''' </summary>
    ''' <remarks></remarks>
    Public Overloads Property ListeChampsSortie() As baseListeChampsSortieTable
        Get
            Return MyBase.ListeChampsSortie
        End Get
        Protected Set(ByVal value As baseListeChampsSortieTable)
            MyBase.SetListeChampsSortie(value)
        End Set
    End Property


#End Region

#Region "Méthodes publiques"

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks></remarks>
    Public Function setChSortieFormuleEgaleChampsEntree(ByVal descChEntree As String, _
                                                     ByVal descChSortie As String) As Boolean
        'Mettre à jours les correspondances constitutives
        Dim b As Boolean
        b = ListeChampsSortie.Item(descChSortie).setChEntree(ListeChampsEntree.Item(descChEntree).chBDD)
        If b Then
            ListeChampsSortie.Item(descChSortie).addCorrespConstitutive(ListeChampsEntree.Item(descChEntree))
            ListeChampsSortie.Item(descChSortie).typeChEntree = typeChEntreeMapping.TABLE
        End If
        Return b
    End Function

    ''' <summary>
    ''' Permet de récupérer les valeurs distinctes d'une variable de la table
    ''' </summary>
    ''' <remarks></remarks>
    Public Function CalculerValeursEntree(ByVal nomChampsEntree As String)
        If ListeChampsEntree.Item(nomChampsEntree).chOutil.valeursDistinctes Is Nothing Then
            '1. Création d'une requête sur le mapping en entrée. Le select contient la correspondance
            'par défaut du même nom que la variable dont on cherche à récupérer les valeurs.
            Dim requeteExtractVal As RequeteBDD = New RequeteBDD(Me, "ReqExtractValeurs")
            requeteExtractVal.addSELECT(ListeChampsEntree.Item(nomChampsEntree))
            '2. Exécution de la requête et stockage du résultat dans les valeurs prises 
            'par le champs cible (après exécution de l'informat par défaut)
            requeteExtractVal.Calculer_DataTable()
            ListeChampsEntree.Item(nomChampsEntree).chOutil.valeursDistinctes = requeteExtractVal.DataTableResultat
            '3. Recherche, parmi toutes les correspondances des autres mapping, s'il y en a qui contiennent comme champs
            'source le champs "nomVariable". Si c'est le cas et si l'informat le permet, 
            'les valeurs prises par le champs cible sont mises à jour.
            ListeChampsSortie.valCorrespChanged(ListeChampsEntree.Item(nomChampsEntree))
        End If
        Return ListeChampsEntree.Item(nomChampsEntree).chOutil.valeursDistinctes
    End Function

#Region "Méthodes d'exécution : récupération des dataTable en entrée et en sortie de la tableBDD"

    ''' <summary>
    ''' Extrait le contenu de la table en sortie dans un fichier Excel
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub execute_Excel(ByVal stockageBDDlocale As Boolean, _
                                  ByVal xlSheet As Excel.Worksheet, _
                                  ByVal iCellDep As Integer, _
                                  ByVal jCellDep As Integer)

        Me.Calculer_DataTable()
        Dim result As DataTable = DataTableResultat
        Dim i As Integer = iCellDep
        Dim j As Integer = jCellDep

        For Each col As DataColumn In result.Columns
            xlSheet.Cells(i, j) = col.ColumnName
            xlSheet.Range(xlSheet.Cells(i, j), xlSheet.Cells(i, j)).Interior.Color = RVBtoVBhexa(0, 0, 0)
            xlSheet.Range(xlSheet.Cells(i, j), xlSheet.Cells(i, j)).Font.Color = RVBtoVBhexa(255, 255, 255)
            j = j + 1
        Next

        i = i + 1
        For Each r As DataRow In result.Rows
            j = jCellDep
            For Each col As DataColumn In result.Columns
                xlSheet.Cells(i, j) = r(col.ColumnName)
                j = j + 1
            Next
            i = i + 1
        Next

    End Sub

    ''' <summary>
    ''' Extrait le contenu de la table en entrée dans un objet DataTable
    ''' </summary>
    ''' <remarks></remarks>
    Protected Overrides Sub execute_DataTable()
        If Not EtatCalcul_DataTable = ValueEtatCalcul.A_JOUR Then
            Dim requeteExtractDataTable As RequeteBDD = New RequeteBDD(Me, "ReqExtractDataTableEntree")
            For Each corresp In ListeChampsEntree
                requeteExtractDataTable.addSELECT(ListeChampsEntree.Item(corresp.Value.description))
            Next
            requeteExtractDataTable.Calculer_DataTable()
            Me.SetDataTableResultat(requeteExtractDataTable.DataTableResultat)
            _DataTableResultats.TableName = "dtble_" & nom
            If Not DataSet Is Nothing Then
                If DataSet.Tables.Contains(_DataTableResultats.TableName) Then DataSet.Tables.Remove(_DataTableResultats.TableName)
                DataSet.Tables.Add(_DataTableResultats)
            End If
            End If
    End Sub

    ''' <summary>
    ''' Extrait le contenu de la table en sortie dans un objet DataTable
    ''' </summary>
    ''' <remarks></remarks>
    Public Function execute_DataTableSortie(ByVal stockageBDDlocale As Boolean, _
                                            Optional ByVal forcerRecalcul As Boolean = False) As DataTable

        Dim result As DataTable = Nothing

        If m_etatExecDataTableSortie.Value = ValueEtatCalcul.A_JOUR And Not forcerRecalcul Then
            result = DataSet.Tables("dtbleSortie_" & nom)
        Else
            Dim requeteExtractDataTableSortie As RequeteBDD = New RequeteBDD(Me, "ReqExtractDataTableSortie")
            For Each corresp In ListeChampsSortie
                requeteExtractDataTableSortie.addSELECT(ListeChampsSortie.Item(corresp.Value.description))
            Next
            requeteExtractDataTableSortie.Calculer_DataTable()
            result = requeteExtractDataTableSortie.DataTableResultat
            If Not result Is Nothing Then
                result.TableName = "dtbleSortie_" & nom
                If stockageBDDlocale Then
                    If DataSet.Tables.Contains(result.TableName) Then DataSet.Tables.Remove(result.TableName)
                    m_etatExecDataTableSortie.Value = ValueEtatCalcul.A_JOUR
                End If
            End If
        End If

        Return result

    End Function

    ''' <summary>
    ''' Extrait le contenu de la table en sortie dans la base de données
    ''' </summary>
    ''' <remarks></remarks>
    Protected Overrides Sub execute_BDD()
    End Sub

#End Region

#End Region

#Region "Mise à jour des métadonnées : Méthodes protégées"

    Protected Property TableMetaDonnees As DataTable
        Get
            Return _dttbleMetaDonnees
        End Get
        Set(ByVal value As DataTable)
            _dttbleMetaDonnees = value
        End Set
    End Property

    ''' <summary>
    ''' Mise à jour de la liste des champs disponibles dans la table à partir des méta-données
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub MAJListesChampsFromMetaDonnees()
        'Récupération des champs présents en entrée
        Dim NouveauxChampsEntree As Dictionary(Of String, ChampsBDD) = New Dictionary(Of String, ChampsBDD)
        For Each r As DataRow In _dttbleMetaDonnees.Rows
            NouveauxChampsEntree.Add(r("COLUMN_NAME"), New ChampsBDD(r("COLUMN_NAME"), _
                                    New FormatChamps(Type.GetType(r("DATA_TYPE_FULLNAME")), _
                                    Type.GetType(r("FORMAT_NAME")))))
        Next
        'Constitution de la nouvelle liste de correspondances en entrée
        Dim NvelleListeChampsEntree As New ListeChampsEntreeTable
        For Each champs As ChampsBDD In NouveauxChampsEntree.Values
            Dim corresp As New Correspondance(Me, _
                                              champs.Nom, _
                                              champs, _
                                              typeChEntreeMapping.TABLE)
            NvelleListeChampsEntree.Add(corresp.description, corresp)
        Next

        ListeChampsEntree = NvelleListeChampsEntree

        RaiseEvent ListeChampsEntreeChanged(Me, New EventArgs)
    End Sub

    Public Event ListeChampsEntreeChanged(ByVal sender As Object, ByVal e As EventArgs)

    ''' <summary>
    ''' Mise à jour des statistiques sur la table
    ''' </summary>
    ''' <remarks></remarks>
    Protected Sub MAJStats()
        Dim da As OleDb.OleDbDataAdapter, ds As New DataSet()

        'Comptage des lignes de la base d'enours
        Connection.Open()
        da = New OleDb.OleDbDataAdapter("Select count(*) from " & NomTableDansBDD, Connection)
        da.Fill(ds, "nbLignesEncours")
        Connection.Close()

        StatsTable.NbLignes = ds.Tables("nbLignesEncours").Rows(0)(0)
        StatsTable.NbColonnes = ListeChampsEntree.Count
    End Sub

    ''' <summary>
    ''' Mise à jour des métadonnées de la table
    ''' </summary>
    ''' <remarks></remarks>
    Protected MustOverride Sub MAJMetaDonnees()

    ''' <summary>
    ''' Mise à jour de la liste de toutes les tables disponibles dans la base de données de la table en cours
    ''' </summary>
    ''' <remarks></remarks>
    Protected MustOverride Sub MAJTablesDispoBDD()

#End Region

End Class
#End Region

